
package com.example.dubbo.controller;

import com.example.dubbo.service.DemoService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @Autowired
    private ApplicationConfig applicationConfig;

    @Autowired
    private RegistryConfig registryConfig;

    @DubboReference
    private DemoService demoService;

//    @DubboReference(interfaceClass = GenericService.class, generic = true)
//    private GenericService genericService;


    @GetMapping("/hello")
    public String hello(@RequestParam String name) {
        try {
            return demoService.sayHello(name);
        } catch (Exception e) {
            // 可根据实际情况进行日志记录和异常处理
            e.printStackTrace();
            return "普通调用出错: " + e.getMessage();
        }
    }

    // 处理泛化调用的方法
    @GetMapping("/generic")
    public String generic(@RequestParam String interfaceName, @RequestParam String methodName, @RequestParam String[] parameterTypes, @RequestParam Object[] parameters) {
        return invokeGenericService(interfaceName, methodName, parameterTypes, parameters);
    }

    public String invokeGenericService(String interfaceName, String methodName, String[] parameterTypes, Object[] parameters) {
        try {
            ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
            reference.setApplication(applicationConfig);
            reference.setRegistry(registryConfig);
            reference.setInterface(interfaceName);
            reference.setGeneric("true"); // 使用字符串形式设置泛化调用
            GenericService genericService = reference.get();
            // 泛化调用
            Object result = genericService.$invoke(
                    methodName, // 方法名
                    parameterTypes, // 参数类型数组
                    parameters // 参数值数组
            );
            return (String) result;
        } catch (Exception e) {
            // 可根据实际情况进行日志记录和异常处理
            e.printStackTrace();
            return "泛化调用出错: " + e.getMessage();
        }
    }
}